/*
* Copyright (C) 2021 ~ 2022 Uniontech Technology Co., Ltd.
*
* Author:      zhangbingyi <zhangbingyi@uniontech.com>
*
* Maintainer:  zhangbingyi <zhangbingyi@uniontech.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "usbstoragesecuritymodel.h"
#include "invokers/invokerfactory.h"
#include "common/systemsettings.h"
#include "gsettingkey.h"
#include "compixmap.h"
#include "widgets/ddialog.h"
#include "widgets/hfloatingdialog.h"

#include <QFileDialog>
#include <QDir>
#include <QPushButton>
#include <QDebug>
#include <QApplication>

#define USB_INFO_SIZE 8 // usb信息种类个数

USBStorageSecurityModel::USBStorageSecurityModel(QObject *parent)
    : QObject(parent)
    , m_systemSettings(new SystemSettings(this))
    , m_globalPermMode(USB_MANAGER_PERM_MODE_RW)
    , m_uiEnableStatus(true)
    , m_usbManagerInvokerInter(nullptr)
    , m_monitorNetFlowInvokerInter(nullptr)
{
    registerUSBConnectionInfoMetaType();
    registerUSBConnectionInfoListMetaType();

    qRegisterMetaType<USBConnectionInfo>("UsbConnectionInfo");

    // invoker
    m_usbManagerInvokerInter = InvokerFactory::GetInstance().CreateInvoker("com.deepin.defender.USBManager",
                                                                           "/com/deepin/defender/USBManager",
                                                                           "com.deepin.defender.USBManager",
                                                                           ConnectType::SYSTEM, this);
    // invoker
    m_monitorNetFlowInvokerInter = InvokerFactory::GetInstance().CreateInvoker("com.deepin.defender.MonitorNetFlow",
                                                                               "/com/deepin/defender/MonitorNetFlow",
                                                                               "com.deepin.defender.MonitorNetFlow",
                                                                               ConnectType::SYSTEM, this);

    // USB链接记录
    m_usbManagerInvokerInter->Connect("SendNeedShowUSBStorageConnList", this, SLOT(onRecvNeedShowRecords(USBConnectionInfoList)));
    m_usbManagerInvokerInter->Connect("SendUSBStorageCtrlInfo", this, SLOT(onReceiveUsbInfo(USBConnectionInfo)));
    m_usbManagerInvokerInter->Connect("SetGlobalPermModeFinished", this, SLOT(onSetGlobalPermModeFininshed(int)));
    m_usbManagerInvokerInter->Connect("HideAllUSBStorageConnLogFinished", this, SLOT(onClearAllUSBStorageConnLogFinished()));
    m_usbManagerInvokerInter->Connect("SendAllUSBStorageConnList", this, SLOT(onRecvAllDevAllConnList(USBConnectionInfoList))); // 导出全部设备全部连接记录

    // 白名单操作
    m_usbManagerInvokerInter->Connect("SendStorageWhitelist", this, SLOT(onRecvWhitelist(USBConnectionInfoList)));
    m_usbManagerInvokerInter->Connect("OperateStorageWhitelistFinished", this, SLOT(onOperateStorageWhitelistFinished(int, USBConnectionInfo))); // 修改返回的值
    m_usbManagerInvokerInter->Connect("OperateBatchStorageWhitelistFinished", this, SLOT(onOperateBatchStorageWhitelistFinished(int, USBConnectionInfoList))); // 批量操作白名单(导入)
    m_usbManagerInvokerInter->Connect("ImportBatchStorageWhitelistFinished", this, SLOT(onImportBatchStorageWhitelistFinished(USBConnectionInfoList))); // 批量操作白名单(导入)

    // 设备详情页
    m_usbManagerInvokerInter->Connect("SendOneDevAllVisibleConnList", this, SLOT(onRecvUSBDetails(USBConnectionInfoList))); // 接收详情页信息
    m_usbManagerInvokerInter->Connect("SendOneDevAllConnList", this, SLOT(onRecvOneDevAllConnList(USBConnectionInfoList))); // 导出详情页某USB设备全部连接日志

    loadConfig();

    //读取白名单
    asyncReadConnectionWhiteLst();
    //读取usb连接记录
    asyncReadNeedShowRecords();
    //清除超过30天记录
    cleanUsbConnectionLog();

    // thread
    m_policyKitHelper = new USBPolicyKitHelper;
    m_policyKitHelper->moveToThread(&m_polKitHelperThread);
    /// 连接从m_policyKitHelper发出的信号
    // 通知去改变usb限制模式
    connect(m_policyKitHelper, SIGNAL(notifyChangeLimitationMode(int)), this, SLOT(asyncSelectLimitationMode(int)));
    // 通知去添加到白名单
    connect(m_policyKitHelper, SIGNAL(notifyAddUsbConnectionWhiteLst(const USBConnectionInfo &)),
            this,  SLOT(notifyAddUsbConnectionWhiteLst(const USBConnectionInfo &)));
    // 通知去添加到白名单
    connect(m_policyKitHelper, SIGNAL(notifyChangeDevPerm(const USBConnectionInfo &)),
            this, SLOT(notifyChangeDevPerm(const USBConnectionInfo &)));

    // 通知去清除usb连接记录
    connect(m_policyKitHelper, SIGNAL(notifyClearUsbConnectionLog()), this, SLOT(asyncClearUsbConnectionLog()));

    // 通知去导入白名单 --白名单页面
    connect(m_policyKitHelper, SIGNAL(notifyShowImportWhitelistDlg()), this, SLOT(showImportWhitelistDlg()));

    // 权限校验完成
    connect(m_policyKitHelper, SIGNAL(checkAuthorizationFinished()), this, SLOT(emitCheckAuthorizationFinished()));

    m_polKitHelperThread.start();

    /// 连接从USBStorageSecurityModel发出的信号
    // 请求确认选择usb限制模式
    connect(this, SIGNAL(requestConfirmSelectLimitationMode(int)), m_policyKitHelper, SLOT(confirmSelectLimitationMode(int)));
    // 请求确认添加到白名单
    connect(this, SIGNAL(requestAuthorizeChangeDevPerm(const USBConnectionInfo &)), m_policyKitHelper, SLOT(authorizeChangeDevPerm(const USBConnectionInfo &)));
    // 请求授权修改白名单设备权限
    connect(this, SIGNAL(requestConfirmAddUsbConnectionWhiteLst(const USBConnectionInfo &)), m_policyKitHelper, SLOT(confirmAddUsbConnectionWhiteLst(const USBConnectionInfo &)));
    // 请求确认清除usb连接记录
    connect(this, SIGNAL(requestConfirmClearUsbConnectionLog()), m_policyKitHelper, SLOT(confirmClearUsbConnectionLog()));
    // 请求确认导入白名单 --白名单页面
    connect(this, SIGNAL(requestConfirmImportWhitelist()), m_policyKitHelper, SLOT(confirmImportWhitelist()));

    /// 连接 m_importAndExportJob发出的信号
    m_importAndExportJob = new USBImportAndExportJob;
    m_importAndExportJob->moveToThread(&m_jobThread);

    // 校验成功 进行白名单导入添加
    connect(m_importAndExportJob, SIGNAL(usbWhitelistVerifySucceed(const USBConnectionInfoList &)), this,
            SLOT(asyncImportBatchStorageWhitelist(const USBConnectionInfoList &)));

    // 白名单导入校验失败 提示弹窗
    connect(m_importAndExportJob, SIGNAL(usbWhitelistInfoVerifyFailed(int, const QString &)), this,
            SLOT(onUSBWhitelistInfoVerifyFailed(int, const QString &)));

    // 白名单导入 校验失败其他场景  提示弹窗
    connect(m_importAndExportJob, SIGNAL(importUSBWhitelistFailed()), this,
            SLOT(onImportWhitelistFailed()));

    // 导出全部设备全部连接记录完成  执行添加日志
    connect(m_importAndExportJob, SIGNAL(exportAllDevConnectionRecordFinished()), this, SLOT(exportOneDevConnectionRecordFinished()));

    // 导出某一个设备全部连接记录完成  执行添加日志
    connect(m_importAndExportJob, SIGNAL(exportOneDevConnectionRecordFinished()), this, SLOT(exportOneDevConnectionRecordFinished()));

    /// 连接从USBStorageSecurityModel发出的信号
    // 请求导入白名单 --白名单页面
    connect(this, SIGNAL(notifyImportUSBWhitelist(const QString &)),
            m_importAndExportJob, SLOT(onImportUSBWhitelist(const QString &)));

    // 请求导出白名单导出模板  -- 白名单页面
    connect(this, SIGNAL(notifyExportWhitelistTemplate(const QString &)),
            m_importAndExportJob, SLOT(onExportWhitelistTemplate(const QString &)));

    // 请求导出全部设备全部连接记录 -- 连接记录页面
    connect(this, SIGNAL(notifyExportAllConnectionRecords(const QString &, const USBConnectionInfoList &)),
            m_importAndExportJob, SLOT(onExportAllDevConnetionRecord(const QString &, const USBConnectionInfoList &)));

    // 请求导出某一个设备全部连接记录 -- 设备详情页面
    connect(this, SIGNAL(notifyExportOneDveConnectionRecords(const QString &, const USBConnectionInfoList &)),
            m_importAndExportJob, SLOT(onExportOneDevConnetionRecord(const QString &, const USBConnectionInfoList &)));

    m_jobThread.start();
}

USBStorageSecurityModel::~USBStorageSecurityModel()
{
    m_policyKitHelper->deleteLater();
    m_policyKitHelper = nullptr;

    m_importAndExportJob->deleteLater();
    m_importAndExportJob = nullptr;

    // 完成后删除线程
    m_polKitHelperThread.quit();
    m_polKitHelperThread.wait();

    m_jobThread.quit();
    m_jobThread.wait();
}

bool USBStorageSecurityModel::isInUDCPDomain()
{
    QDBusMessage msg = DBUS_BLOCK_INVOKE(m_usbManagerInvokerInter, "IsInUDCPDomain");
    GET_MESSAGE_VALUE(bool, isIn, msg);

    return isIn;
}

int USBStorageSecurityModel::getGlobalPermMode()
{
    return m_globalPermMode;
}

void USBStorageSecurityModel::loadConfig()
{
    QDBusMessage msg = DBUS_BLOCK_INVOKE(m_usbManagerInvokerInter, "GetGlobalPermMode");
    GET_MESSAGE_VALUE(int, mode, msg);

    m_globalPermMode = mode;
}

// 读取 USB 连接记录
void USBStorageSecurityModel::asyncReadNeedShowRecords()
{
    DBUS_NOBLOCK_INVOKE(m_usbManagerInvokerInter, "AsyncGetNeedShowUSBStorageConnList");
}

// 读取 USB 白名单
void USBStorageSecurityModel::asyncReadConnectionWhiteLst()
{
    DBUS_NOBLOCK_INVOKE(m_usbManagerInvokerInter, "AsyncGetStorageWhitelist");
}

void USBStorageSecurityModel::onReceiveUsbInfo(const USBConnectionInfo &info)
{
    m_usbConnectionInfoLst.append(info);
    //根据当前时间清理连接记录
    cleanUsbConnectionLog();
    Q_EMIT sendUsbConnectionLogInfo(info);

    // 刷新白名单中Name信息，在下次打开白名单列表会刷新
    updateNameAndSizeInWhitelist(info);
}

// 接收到DBus USB详情列表数据
void USBStorageSecurityModel::onRecvUSBDetails(const USBConnectionInfoList &list)
{
    // 通知界面去接收信息
    Q_EMIT sendUSBDetails(list);
}

// 接收到导出某一设备详情日志的全部数据 并执行导出操作
void USBStorageSecurityModel::onRecvOneDevAllConnList(const USBConnectionInfoList &list)
{
    // 向USBImportAndExportJob 发送信号 导出某一设备的全部记录
    Q_EMIT notifyExportOneDveConnectionRecords(m_detailsSavePath, list);

    // 界面禁用状态
    setUIEnableStatus(false);
}

// 接收到导出全部设备全部连接记录  并执行导出操作
void USBStorageSecurityModel::onRecvAllDevAllConnList(const USBConnectionInfoList &list)
{
    // 向USBImportAndExportJob 发送信号 导出全部记录
    Q_EMIT notifyExportAllConnectionRecords(m_allConnSavePath, list);

    // 界面禁用状态
    setUIEnableStatus(false);
}

void USBStorageSecurityModel::notifyAddUsbConnectionWhiteLst(const USBConnectionInfo &info)
{
    this->asyncOperateStorageWhitelist(USB_MANAGER_OP_TYPE_ADD, info);
}

void USBStorageSecurityModel::notifyChangeDevPerm(const USBConnectionInfo &info)
{
    this->asyncOperateStorageWhitelist(USB_MANAGER_OP_TYPE_MODIFY, info);
}

void USBStorageSecurityModel::emitCheckAuthorizationFinished()
{
    // 设置数据处理对象中的操作按钮状态
    this->setUIEnableStatus(true);
    Q_EMIT this->checkAuthorizationFinished();
}

void USBStorageSecurityModel::exportOneDevConnectionRecordFinished()
{
    // 界面解除禁用状态
    setUIEnableStatus(true);

    // 执行添加日志 "连接记录导出"
    DBUS_NOBLOCK_INVOKE(m_monitorNetFlowInvokerInter, "AddSecurityLog", SECURITY_LOG_TYPE_TOOL, tr("Connection records exported"));
}

void USBStorageSecurityModel::onUSBWhitelistInfoVerifyFailedHelp(int index, QString)
{
    DDialog* dialog = qobject_cast<DDialog*>(sender());
    switch (index) {
    case 0:
        dialog->close();
        break;
    default:
        break;
    }
}

// 接收到全局USB管控权限模式完成设置   记录日志&改变界面显示
void USBStorageSecurityModel::onSetGlobalPermModeFininshed(int mode)
{
    // 接收DBus USB全局读写限制
    m_globalPermMode = mode;

    // 通知去改变usb限制模式
    Q_EMIT notifyChangeLimitationMode(mode);

    // 添加日志
    QString logStr;
    if (USB_MANAGER_PERM_MODE_RW == mode) {
        logStr = tr("Changed the connection of USB storage devices to \"Read-write\"");
    } else if (USB_MANAGER_PERM_MODE_RO == mode) {
        logStr = tr("Changed the connection of USB storage devices to \"Read only\"");
    } else if (USB_MANAGER_PERM_MODE_NO == mode) {
        logStr = tr("Changed the connection of USB storage devices to \"Block\"");
    }
    DBUS_NOBLOCK_INVOKE(m_monitorNetFlowInvokerInter, "AddSecurityLog", SECURITY_LOG_TYPE_TOOL, logStr);
}

void USBStorageSecurityModel::onRecvNeedShowRecords(const USBConnectionInfoList &list)
{
    // 接收DBus USB连接数据列表
    m_usbConnectionInfoLst = list;
    Q_EMIT sendNeedShowRecords(m_usbConnectionInfoLst);
}

void USBStorageSecurityModel::onRecvWhitelist(const USBConnectionInfoList &list)
{
    // 接收DBus 白名单数据列表
    m_usbWhitelistInfoLst = list;

    Q_EMIT sendAllWhitelist(m_usbWhitelistInfoLst);
}

// 对USB白名单 进行设置  增删改
void USBStorageSecurityModel::asyncOperateStorageWhitelist(int type, const USBConnectionInfo &info)
{
    DBUS_NOBLOCK_INVOKE(m_usbManagerInvokerInter, "AsyncOperateStorageWhitelist", type, QVariant::fromValue(info));
}

// 接收 白名单 批量设置信号  调用DBUS
void USBStorageSecurityModel::asyncOperateBatchStorageWhitelist(int type, const USBConnectionInfoList &list)
{
    DBUS_NOBLOCK_INVOKE(m_usbManagerInvokerInter, "AsyncOperateBatchStorageWhitelist", type, QVariant::fromValue(list));
}

void USBStorageSecurityModel::asyncImportBatchStorageWhitelist(const USBConnectionInfoList &list)
{
    DBUS_NOBLOCK_INVOKE(m_usbManagerInvokerInter, "AsyncImportBatchStorageWhitelist", QVariant::fromValue(list));
}

// 白名单模板下载
void USBStorageSecurityModel::exportWhitelistTemplate()
{
    QString savePath = QFileDialog::getSaveFileName(nullptr, tr("Save to"), QDir::homePath() + "/Desktop/" + tr("USB Whitelist Template") + ".csv", "*.csv");

    // 向USBImportAndExportJob 发送信号进行验证
    if (!savePath.isEmpty()) {
        Q_EMIT notifyExportWhitelistTemplate(savePath);
    }
}

void USBStorageSecurityModel::showImportWhitelistDlg()
{
    QString path = QFileDialog::getOpenFileName(nullptr, tr("Save to"), QDir::homePath() + "/Desktop/", "*.csv");
    // 向USBImportAndExportJob 发送信号进行验证
    if (!path.isEmpty()) {
        // 界面禁用状态
        setUIEnableStatus(false);
        Q_EMIT notifyImportUSBWhitelist(path);
    } else {
        // 解除界面禁用状态
        setUIEnableStatus(true);
    }
}

// 导入白名单校验失败
void USBStorageSecurityModel::onUSBWhitelistInfoVerifyFailed(int row, const QString &name)
{
    // 解决bug-127823 Wayland白名单导入失败弹出异常提示框，将其他界面置顶于异常提示框后无法操作界面
    QWidget *dlgParent = nullptr;
    foreach (QWidget *widget, QApplication::topLevelWidgets()) {
        if (widget->objectName() == "USBWhiteListDialogMainWindow") {
            dlgParent = widget;
            break;
        }
    }

    if (dlgParent == nullptr) {
        return;
    }
    DDialog *dialog = new DDialog(dlgParent);
    dialog->setAccessibleName("importWhitelistErrorDialog");
    dialog->setMinimumSize(QSize(TIP_DIALOG_WIDTH, TIP_DIALOG_HEIGHT));
    dialog->setMaximumSize(QSize(TIP_DIALOG_WIDTH, TIP_DIALOG_HEIGHT));
    dialog->setIcon(QIcon::fromTheme(DIALOG_TIP_YELLOW));
    dialog->setModal(true);
    dialog->setMessage(tr("\"%2\" data error in the line %1. Please check and try again.").arg(row).arg(name));
    dialog->setWordWrapMessage(true);
    dialog->setAttribute(Qt::WA_DeleteOnClose);
    // 确定推荐
    QPushButton *okBtn = new QPushButton(dialog);
    okBtn->setText(tr("OK", "button"));
    okBtn->setObjectName("okButton");
    okBtn->setAccessibleName("errordialog_okButton");
    okBtn->setAttribute(Qt::WA_NoMousePropagation);
    dialog->insertButton(0, okBtn, false);
    connect(dialog, SIGNAL(buttonClicked()), this, SLOT(onUSBWhitelistInfoVerifyFailedHelp(int, QString)));
    dialog->show();

    // 解除界面禁用状态
    setUIEnableStatus(true);
}

// 白名单校验失败 其他场景
void USBStorageSecurityModel::onImportWhitelistFailed()
{
    // 解决bug-127823 Wayland白名单导入失败弹出异常提示框，将其他界面置顶于异常提示框后无法操作界面
    QWidget *dlgParent = nullptr;
    foreach (QWidget *widget, QApplication::topLevelWidgets()) {
        if (widget->objectName() == "USBWhiteListDialogMainWindow") {
            dlgParent = widget;
            break;
        }
    }

    if (dlgParent == nullptr) {
        return;
    }
    DDialog dialog(dlgParent);
    dialog.setAccessibleName("importWhitelistOtherErrorDialog");
    dialog.setMinimumSize(QSize(TIP_DIALOG_WIDTH, TIP_DIALOG_HEIGHT));
    dialog.setMaximumSize(QSize(TIP_DIALOG_WIDTH, TIP_DIALOG_HEIGHT));
    dialog.setIcon(QIcon::fromTheme(DIALOG_TIP_YELLOW));
    dialog.setModal(true);
    dialog.setMessage(tr("Import failed. Please try later."));
    dialog.setWordWrapMessage(true);
    dialog.addButton(tr("OK", "Button"), false);

    dialog.exec();

    // 解除界面禁用状态
    setUIEnableStatus(true);
}

// 白名单导入成功操作
void USBStorageSecurityModel::onImportBatchStorageWhitelistFinished(const USBConnectionInfoList &list)
{
    // 解除界面禁用状态
    setUIEnableStatus(true);

    Q_EMIT importBatchStorageWhitelistFinished(list);
}

// 接收到DBus 白名单操作状态限制结果
void USBStorageSecurityModel::onOperateStorageWhitelistFinished(int type, const USBConnectionInfo &info)
{
    // 修改权限
    if (USB_MANAGER_OP_TYPE_MODIFY == type) {
        for (USBConnectionInfo &usbinfo : m_usbWhitelistInfoLst) {
            if (usbinfo.serial == info.serial && usbinfo.productID == info.productID && usbinfo.vendorID == info.vendorID) {
                usbinfo.permMode = info.permMode;
                // 添加日志
                QString logStr;
                logStr = tr("Changed the policy of devices in the whitelist: Device = %1, SN = %2, PID = %3, VID = %4, Policy = %5")
                             .arg(info.name)
                             .arg(info.serial)
                             .arg(info.productID)
                             .arg(info.vendorID)
                             .arg(info.permMode == 0 ? tr("Read-write") : tr("Read only"));
                DBUS_NOBLOCK_INVOKE(m_monitorNetFlowInvokerInter, "AddSecurityLog", SECURITY_LOG_TYPE_TOOL, logStr);
            }
        }
    }
    // 从白名单列表中移除
    if (USB_MANAGER_OP_TYPE_REMOVE == type) {
        for (int i = m_usbWhitelistInfoLst.count() - 1; i >= 0; --i) {
            const USBConnectionInfo &usbinfo = m_usbWhitelistInfoLst.at(i);
            if (usbinfo.serial == info.serial && usbinfo.productID == info.productID && usbinfo.vendorID == info.vendorID) {
                m_usbWhitelistInfoLst.removeAt(i);
                Q_EMIT removeWhitelistFinished(info);
                // 添加日志
                QString logStr;
                logStr = tr("Removed from whitelist: Device = %1, SN = %2, PID = %3, VID = %4, Policy = %5")
                             .arg(info.name)
                             .arg(info.serial)
                             .arg(info.productID)
                             .arg(info.vendorID)
                             .arg(info.permMode == 0 ? tr("Read-write") : tr("Read only"));
                DBUS_NOBLOCK_INVOKE(m_monitorNetFlowInvokerInter, "AddSecurityLog", SECURITY_LOG_TYPE_TOOL, logStr);
            }
        }
    }
    // 添加到白名单列表中
    if (USB_MANAGER_OP_TYPE_ADD == type) {
        m_usbWhitelistInfoLst.append(info);
        Q_EMIT addUSBWhitelistFinished(info);
        // 成功添加到白名单弹窗提示
        Q_EMIT notifyShowAddWhitelistTip();
        // 添加日志
        QString logStr;
        logStr = tr("Added to whitelist: Device = %1, SN = %2, PID = %3, VID = %4, Policy = %5")
                     .arg(info.name)
                     .arg(info.serial)
                     .arg(info.productID)
                     .arg(info.vendorID)
                     .arg(info.permMode == 0 ? tr("Read-write") : tr("Read only"));
        DBUS_NOBLOCK_INVOKE(m_monitorNetFlowInvokerInter, "AddSecurityLog", SECURITY_LOG_TYPE_TOOL, logStr);
    }

    // 发送操作完成信号
    Q_EMIT operateStorageWhitelistFinished(type, info);
}

// 接收到DBus 白名单批量操作状态结果
void USBStorageSecurityModel::onOperateBatchStorageWhitelistFinished(int type, const USBConnectionInfoList &list)
{
    // 添加到白名单列表中
    if (USB_MANAGER_OP_TYPE_ADD == type) {
        // 添加到缓存
        m_usbWhitelistInfoLst.append(list);
        // 添加日志
        for (USBConnectionInfo info : list) {
            QString logStr;
            logStr = tr("Added to whitelist: Device = %1, SN = %2, PID = %3, VID = %4, Policy = %5")
                         .arg(info.name)
                         .arg(info.serial)
                         .arg(info.productID)
                         .arg(info.vendorID)
                         .arg(info.permMode == 0 ? tr("Read-write") : tr("Read only"));
            DBUS_NOBLOCK_INVOKE(m_monitorNetFlowInvokerInter, "AddSecurityLog", SECURITY_LOG_TYPE_TOOL, logStr);

            // 通知连接记录界面改变
            Q_EMIT addUSBWhitelistFinished(info);
        }

        Q_EMIT addBatchUSBWhitelistBatchFinished(list);
    }

    // 修改到白名单列表中
    if (USB_MANAGER_OP_TYPE_MODIFY == type) {
        for (USBConnectionInfo info : list) {
            for (USBConnectionInfo &usbinfo : m_usbWhitelistInfoLst) {
                if (usbinfo.serial == info.serial && usbinfo.productID == info.productID && usbinfo.vendorID == info.vendorID) {
                    usbinfo.name = info.name;
                    usbinfo.permMode = info.permMode;
                }
            }

            // 添加日志
            QString logStr;
            logStr = tr("Changed the policy of devices in the whitelist: Device = %1, SN = %2, PID = %3, VID = %4, Policy = %5")
                         .arg(info.name)
                         .arg(info.serial)
                         .arg(info.productID)
                         .arg(info.vendorID)
                         .arg(info.permMode == 0 ? tr("Read-write") : tr("Read only"));
            DBUS_NOBLOCK_INVOKE(m_monitorNetFlowInvokerInter, "AddSecurityLog", SECURITY_LOG_TYPE_TOOL, logStr);
        }

        Q_EMIT modifyBatchUSBWhitelistBatchFinished(list);
    }

    // UI状态启用
    setUIEnableStatus(true);
}

// 清除连接记录
void USBStorageSecurityModel::asyncClearUsbConnectionLog()
{
    // 调用Dbus接口清除连接记录
    DBUS_NOBLOCK_INVOKE(m_usbManagerInvokerInter, "AsyncHideAllUSBStorageConnLog");
}

void USBStorageSecurityModel::onClearAllUSBStorageConnLogFinished()
{
    // 清空列表
    m_usbConnectionInfoLst.clear();

    // 发送清除所有连接记录完成信号
    Q_EMIT clearAllDevRecordsFinished();

    // 添加日志
    QString logStr = tr("Connection records cleared");
    DBUS_NOBLOCK_INVOKE(m_monitorNetFlowInvokerInter, "AddSecurityLog", SECURITY_LOG_TYPE_TOOL, logStr);
}

void USBStorageSecurityModel::cleanUsbConnectionLog()
{
    QList<USBConnectionInfo> usbConnectionInfoLstTmp = m_usbConnectionInfoLst;
    m_usbConnectionInfoLst.clear();
    QDateTime limitTime = QDateTime::currentDateTime().addDays(-30);
    for (USBConnectionInfo info : usbConnectionInfoLstTmp) {
        QDateTime infoTime = QDateTime::fromString(info.addedTime, USB_MANAGER_CONN_TIME_FORMATION);
        //只记录30天以内的连接数据
        if (limitTime < infoTime) {
            m_usbConnectionInfoLst.append(info);
        }
    }
}

// 新连接USB的Name改变，更新白名单列表Name信息
void USBStorageSecurityModel::updateNameAndSizeInWhitelist(const USBConnectionInfo &info)
{
    for (int i = 0; i < m_usbWhitelistInfoLst.size(); i++) {
        USBConnectionInfo oldInfo = m_usbWhitelistInfoLst.at(i);
        if (oldInfo.serial == info.serial && oldInfo.vendorID == info.vendorID && oldInfo.productID == info.productID) {
            oldInfo.name = info.name;
            oldInfo.size = info.size;
            m_usbWhitelistInfoLst.replace(i, oldInfo);

            // 通知白名单弹窗修改界面数据
            Q_EMIT notifyUpdateNameAndSizeInWhitelist(oldInfo, info.name, info.size);
            return;
        }
    }
}

// 调取某一个USB设备详情信息
void USBStorageSecurityModel::asyncReadUSBDetails(const USBConnectionInfo &info)
{
    DBUS_NOBLOCK_INVOKE(m_usbManagerInvokerInter, "AsyncGetOneDevAllVisibleConnList", QVariant::fromValue(info));
}

// USB设备详情页 导出功能相关
void USBStorageSecurityModel::asyncGetOneDevAllConnList(const QString &path, const USBConnectionInfo &info)
{
    m_detailsSavePath = path;
    DBUS_NOBLOCK_INVOKE(m_usbManagerInvokerInter, "AsyncGetOneDevAllConnList", QVariant::fromValue(info));
}

// USB连接记录 导出全部设备全部连接记录
void USBStorageSecurityModel::asyncGetAllUSBStorageConnList(const QString &path)
{
    m_allConnSavePath = path;
    DBUS_NOBLOCK_INVOKE(m_usbManagerInvokerInter, "AsyncGetAllUSBStorageConnList");
}

// 显示悬浮弹框
void USBStorageSecurityModel::showFloatMsg(QWidget *widget, const QString &iconPath, const QString &msg, int dura)
{
    HFloatingDialog fdlg;
    fdlg.setDuration(2000);
    fdlg.setText(msg);
    fdlg.setIconPixmap(QPixmap(iconPath));
    fdlg.exec();
}

// 判断该USB设备是否已存入在白名单列表中
bool USBStorageSecurityModel::isUsbDeviceInWhiteList(const QString &serial, const QString &vendor, const QString &product)
{
    QList<USBConnectionInfo>::iterator beginIter = m_usbWhitelistInfoLst.begin();
    QList<USBConnectionInfo>::iterator endIter = m_usbWhitelistInfoLst.end();
    QList<USBConnectionInfo>::iterator findIter;
    findIter = std::find_if(beginIter, endIter, [&serial, &vendor, &product](const USBConnectionInfo &info) {
        return (serial == info.serial
                && vendor == info.vendorID
                && product == info.productID);
    });

    return endIter != findIter;
}

void USBStorageSecurityModel::setUIEnableStatus(bool enable)
{
    m_uiEnableStatus = enable;
    // 通知界面刷新
    Q_EMIT notifyWhitelistDlgUpdate();
}

void USBStorageSecurityModel::asyncSelectLimitationMode(int mode)
{
    m_globalPermMode = mode;
    DBUS_NOBLOCK_INVOKE(m_usbManagerInvokerInter, "AsyncSetGlobalPermMode", mode);
}
